﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using System.Security.Cryptography;
using System.Windows.Browser;

namespace ecpuCalc
{
    public partial class MainPage : UserControl
    {
        public static Analytics _analytics = new Analytics();

        private Thread _thread1;
        private Thread _thread2;
        private Thread _thread3;
        private Thread _threadR;

        private static TextBlock _thread1Value;
        private static TextBlock _thread2Value;
        private static TextBlock _thread3Value;

        private static ProgressBar _cpuUsageBar;
        private static TextBlock _cpuUsageValue;

        private static int _count1 = 0;
        private static int _count2 = 0;
        private static int _count3 = 0;

        private static int _targetCount = 12345678;
        private static string _targetHash;

        private static bool _done = true;
        public bool Done
        {
            get { return _done; }
            set { _done = value; }
        }

        private static bool _paused = false;
        public bool Paused
        {
            get { return _paused; }
            set { _paused = value; }
        }

        public MainPage()
        {
            InitializeComponent();

            HtmlPage.RegisterScriptableObject("ecpuCalc", this);

            _thread1Value = thread1_value;
            _thread2Value = thread2_value;
            _thread3Value = thread3_value;

            _cpuUsageValue = useCPU_value;
            _cpuUsageBar = useCPU_bar;

            _targetHash = GetSHA1Hash(_targetCount.ToString());

            _threadR = new Thread(DoRendering);
            _threadR.Start();
        }

        public static void DoRendering()
        {
            while (true)
            {
                lock (_analytics)
                {
                    _cpuUsageBar.Dispatcher.BeginInvoke(delegate()
                    {
                        _cpuUsageBar.Value = _analytics.AverageProcessLoad;
                    });

                    _cpuUsageValue.Dispatcher.BeginInvoke(delegate()
                    {
                        _cpuUsageValue.Text = _analytics.AverageProcessLoad.ToString();
                    });
                }
                Thread.Sleep(100);
            }
        }

        private static string GetSHA1Hash(string input)
        {
            SHA1 sha = new SHA1Managed();
            byte[] bs = System.Text.Encoding.UTF8.GetBytes(input);
            bs = sha.ComputeHash(bs);
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            foreach (byte b in bs)
            {
                sb.Append(b.ToString("x2").ToLower());
            }
            string hash = sb.ToString();
            return hash;
        }

        private void StartThreads()
        {
            _done = false;

            _thread1 = new Thread(DoThread1);
            _thread1.Start();
            _thread2 = new Thread(DoThread2);
            _thread2.Start();
            _thread3 = new Thread(DoThread3);
            _thread3.Start();

        }

        public void DoThread1()
        {
            string hash;
            while (!_done)
            {
                this.Dispatcher.BeginInvoke(() =>
                {
                    if (_paused)
                    {
                        //System.Threading.Thread.Sleep(50);
                    }
                    else
                    {
                        hash = GetSHA1Hash(_count1.ToString());
                        if (0 == String.Compare(hash, _targetHash))
                        {
                            _done = true;
                        }
                        _count1++;
                        _thread1Value.Dispatcher.BeginInvoke(delegate()
                        {
                            _thread1Value.Text = hash;

                        });
                    }
                });
                System.Threading.Thread.Sleep(5);
            }
        }

        public void DoThread2()
        {
            string hash;
            while (!_done)
            {
                this.Dispatcher.BeginInvoke(() =>
                {
                    if (_paused)
                    {
                        //System.Threading.Thread.Sleep(50);
                    }
                    else
                    {
                        hash = GetSHA1Hash(_count2.ToString());
                        if (0 == String.Compare(hash, _targetHash))
                        {
                            _done = true;
                        }
                        _count2++;
                        _thread2Value.Dispatcher.BeginInvoke(delegate()
                        {
                            _thread2Value.Text = hash;

                        });
                    }
                });
                System.Threading.Thread.Sleep(10);
            }
        }

        public void DoThread3()
        {
            string hash;
            while (!_done)
            {
                this.Dispatcher.BeginInvoke(() =>
                {
                    if (_paused)
                    {
                        //System.Threading.Thread.Sleep(50);
                    }
                    else
                    {
                        hash = GetSHA1Hash(_count3.ToString());
                        if (0 == String.Compare(hash, _targetHash))
                        {
                            _done = true;
                        }
                        _count3++;
                        _thread3Value.Dispatcher.BeginInvoke(delegate()
                        {
                            _thread3Value.Text = hash;

                        });
                    }
                });
                System.Threading.Thread.Sleep(15);
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (false == _done)
            {
                _done = true;
            }
            else
            {
                StartThreads();
            }
        }

        [ScriptableMember]
        public void PauseEvent()
        {
            _paused = true;
            ifPaused_text.Text = "Paused";
        }

        [ScriptableMember]
        public void UnpauseEvent()
        {
            _paused = false;
            ifPaused_text.Text = "";
        }
    }
}
